package com.ja.openchat.viewmodels;

import static com.blankj.utilcode.util.StringUtils.getString;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.ja.openchat.R;
import com.ja.openchat.data.LoginRepository;
import com.ja.openchat.data.RegisterVue;
import com.ja.openchat.data.TabExMenuResult;
import com.ja.openchat.http.HttpClient;
import com.ja.openchat.http.HttpUtil;
import com.ja.openchat.http.HttpVueClient;
import com.ja.openchat.ui.MainActivity;
import com.ja.openchat.ui.login.LoginByPhoneFragment;
import com.ja.openchat.ui.login.RegisterFragment;
import com.ja.openchat.ui.login.SetNickNameFragment;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.model.Response;
import com.sahooz.library.Country;
import com.sahooz.library.CountryPickFragment;
import com.zy.openchat.App;
import com.zy.openchat.core.manager.AuthUserManager;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.manager.TgEvent;
import com.zy.openchat.core.manager.TgResponse;
import com.zy.openchat.core.manager.TgResultBlock;
import com.zy.openchat.core.model.config.AppConfigInfo;
import com.zy.openchat.core.model.config.TabExMenuInfo;
import com.zy.openchat.core.model.user.UserInfo;
import com.zy.openchat.util.Common;

import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.Map;

import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingAction;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.binding.command.BindingConsumer;
import me.goldze.mvvmhabit.bus.Messenger;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.KLog;


public class LoginViewModel extends BaseViewModel<LoginRepository> {
    //用户名的绑定
    public ObservableField<String> userName = new ObservableField<>("");
    public ObservableField<Country> country = new ObservableField<>(new Country(86, App.getInstanse().getString(R.string.china_text), "CN", 0));

    //密码的绑定
    public ObservableField<String> password = new ObservableField<>("");
    public ObservableField<String> countCode = new ObservableField<>("+86");
    //用户名清除按钮的显示隐藏绑定
    public ObservableInt clearBtnVisibility = new ObservableInt(View.INVISIBLE);
    public ObservableInt pwdBtnVisibility = new ObservableInt(View.INVISIBLE);
    //封装一个界面发生改变的观察者
    public UIChangeObservable uc = new UIChangeObservable();
    private String curUsername;
    public static final String TOKEN_LOGINVIEWMODEL_FINISH = "token_loginviewmodel_finish";

    public ObservableField<Boolean> isRead = new ObservableField<Boolean>(true);


    public class UIChangeObservable {
        //密码开关观察者
        public SingleLiveEvent<Boolean> pSwitchEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<Boolean> showLoginByPhoneEvent = new SingleLiveEvent<>();
    }

    public LoginViewModel(@NonNull Application application, LoginRepository repository) {
        super(application, repository);
        //从本地取得数据绑定到View层
//        userName.set(model.getUserName());
        AppConfigInfo appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
        uc.showLoginByPhoneEvent.setValue(appConfigInfo == null || appConfigInfo.phone_code_login);
        Messenger.getDefault().register(this, LoginViewModel.TOKEN_LOGINVIEWMODEL_FINISH, () -> finish());
    }

    //清除用户名的点击事件, 逻辑从View层转换到ViewModel层
    public BindingCommand clearUserNameOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            userName.set("");
        }
    });
    //密码显示开关  (你可以尝试着狂按这个按钮,会发现它有防多次点击的功能)
    public BindingCommand passwordShowSwitchOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            //让观察者的数据改变,逻辑从ViewModel层转到View层，在View层的监听则会被调用
            uc.pSwitchEvent.setValue(uc.pSwitchEvent.getValue() == null || !uc.pSwitchEvent.getValue());
        }
    });
    //用户名长度改变的回调事件
    public BindingCommand onTextChangeCommand = new BindingCommand<>(new BindingConsumer<String>() {
        @Override
        public void call(String s) {
            KLog.d("onTextChangeCommand==" + s);
            if (TextUtils.isEmpty(s)) {
                clearBtnVisibility.set(View.INVISIBLE);
            } else {
                clearBtnVisibility.set(View.VISIBLE);
            }
        }
    });
    //用户名输入框焦点改变的回调事件
    public BindingCommand<Boolean> onFocusChangeCommand = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean hasFocus) {
            if (hasFocus && !TextUtils.isEmpty(userName.get())) {
                clearBtnVisibility.set(View.VISIBLE);
            } else {
                clearBtnVisibility.set(View.INVISIBLE);
            }
        }
    });
    public BindingCommand<Boolean> onPwdFocusChangeCommand = new BindingCommand<>(new BindingConsumer<Boolean>() {
        @Override
        public void call(Boolean hasFocus) {
            if (hasFocus) {
                pwdBtnVisibility.set(View.VISIBLE);
            } else {
                pwdBtnVisibility.set(View.INVISIBLE);
            }
        }
    });
    //登录按钮的点击事件
    public BindingCommand loginOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            login();
        }
    });
    //手机号登录按钮的点击事件
    public BindingCommand loginByPhoneOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
//            startContainerActivity(LoginByPhoneFragment.class.getCanonicalName());
            finish();
        }
    });
    //注册按钮的点击事件
    public BindingCommand registerUserOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startContainerActivity(RegisterFragment.class.getCanonicalName());
        }
    });

    private void login() {
        click_login();
    }

    private void click_login() {

        //用户名
        if (StringUtils.isEmpty(userName.get())) {
            showWarnTip(getString(R.string.username_null_hint));
            return;
        }
        //密码
        if (StringUtils.isEmpty(password.get())) {
            showWarnTip(getString(R.string.password_null_hint));
            return;
        }
        //协议
        if (!isRead.get()) {
            showWarnTip(getString(R.string.privacy_null_hint));
            return;
        }

        UserInfo.getUserInfo().isPasswordLoginType = true;
        UserInfo.getUserInfo().isPasswordRegisterType = false;
        UserInfo.getUserInfo().phone_number = null;
        Map<String, Object> parameters = new HashMap<>();
        if (!TextUtils.isEmpty(userName.get())) {
            if (Character.isDigit(userName.get().charAt(0))) {
                String username = String.format("%s%s", countCode.get(), userName.get()).replace("+", "");
                curUsername = username;
                parameters.put("phoneNumber", username);
            } else {
                curUsername = userName.get();
                parameters.put("userName", userName.get());
            }
        }
        parameters.put("password", Common.MD5(password.get()));
        showProgress();
        TelegramManager.getTelegramManager().setAuthenticationPhoneNumber(getApplication(), new Gson().toJson(parameters), new TgResultBlock<TgResponse>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {

                if (!obj.ok) {
                    hideProgress();
                    //{"@type":"error","code":400,"message":"PASSWORD_VERIFY_INVALID","@extra":4}
                    //USER_PASSWORD_NEEDED 必须输入密码
//                        USERNAME_NOT_EXIST 用户名不存在
//                        USER_PASSWORD_NOT_SET 用户未设置密码
//                        PASSWORD_VERIFY_INVALID 密码校验错误
//                        IP_ADDRESS_BANNED 登录ip被禁用
//                        USER_BINDED_IP_ADDRESS 登录用户已经绑定ip
                    if (obj.errCode == 400) {
                        if ("400_USERNAME_NOT_EXIST".equals(obj.errString)) {
                            showErrorTip(getApplication().getString(R.string.invalid_username));
                            return;
                        }
                        if ("400_USER_PASSWORD_NOT_SET".equals(obj.errString)) {
                            showErrorTip(getApplication().getString(R.string.password_not_set_use_phone));
                            return;
                        }
                        if ("400_PASSWORD_VERIFY_INVALID".equals(obj.errString)) {
                            showErrorTip(getApplication().getString(R.string.invalid_password));
                            return;
                        }
                        if ("400_IP_ADDRESS_BANNED".equals(obj.errString)) {
                            showErrorTip(getApplication().getString(R.string.login_ip_disabled));
                            return;
                        }
                        if ("400_USER_BINDED_IP_ADDRESS".equals(obj.errString)) {
                            showErrorTip(getApplication().getString(R.string.user_ip_bound));
                            return;
                        }
                    }
                    if (!TextUtils.isEmpty(obj.errString)) {
                        if (obj.errString.contains("PHONE_PASSWORD_FLOOD")) {
                            AppConfigInfo appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
                            showErrorTip(String.format(getApplication().getString(R.string.pwd_wrong_much), Common.getPasswordFloodIntervalStr(appConfigInfo == null ? 3600 : appConfigInfo.password_flood_interval)));
                            return;
                        }
                        if (obj.errString.contains("PHONE_NUMBER_BANNED")) {
                            showErrorTip(getString(R.string.account_banned));
                            return;
                        }
                    }
                    showErrorTip(getApplication().getString(R.string.wrong_pwd_or_username));
                } else {

                    HttpVueClient.getInstance().post("/v1/site/login", "DYNAMIC")
                            .params("username", userName.get())
                            .params("password", "123456")
                            .params("group", "app")
                            .execute(new AbsCallback() {
                                @Override
                                public Object convertResponse(okhttp3.Response response) throws Throwable {
                                    String result = response.body().string();


                                    return new Gson().fromJson(result, RegisterVue.class);
                                }

                                @Override
                                public void onSuccess(Response response) {
                                    hideProgress();
                                    RegisterVue result = (RegisterVue) response.body();
                                    if (result != null) {

                                        if (result.getCode() == 200) {

                                            SharedPreferences.Editor editor = App.getInstanse().getSharedPreferences("config", Context.MODE_PRIVATE).edit();
                                            editor.putString("Access_token", result.getData().getAccess_token());
                                            editor.putString("userInfo", new Gson().toJson(result.getData()));
                                            editor.apply();


                                            AuthUserManager.cleanDestroyFolder();
                                            //登录
                                            AuthUserManager.getAuthUserManager().login(curUsername, UserInfo.getUserInfo().data_directory);
                                            //跳转主页面
                                            startActivity(MainActivity.class);
                                            //更新手机号
                                            if (!StringUtils.isEmpty(UserInfo.getUserInfo().phone_number)) {
                                                AuthUserManager.getAuthUserManager().updateCurrentUserPhone(UserInfo.getUserInfo().phone_number);
                                            }
                                            finish();
                                        } else showErrorTip(result.getMessage());

                                    } else {
                                        showErrorTip("登录失败");
                                    }
                                }
                            });

                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                hideProgress();
                showErrorTip(getString(R.string.request_error));
            }
        });
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onTgEvent(final TgEvent tg_event) {
        if (flagStop) return;
        switch (tg_event.event) {
            case EUser_Td_Input_Code_ByPasswordWay:
                sendDefaultCode();
                break;
            case EUser_Td_Register:
                //设置昵称界面
                Bundle bundle = new Bundle();
                bundle.putString("curUsername", curUsername);
                startContainerActivity(SetNickNameFragment.class.getCanonicalName(), bundle);
                break;
            case EUser_Td_Ready:


                //清理数据
//                AuthUserManager.cleanDestroyFolder();
//                //登录
//                AuthUserManager.getAuthUserManager().login(curUsername, UserInfo.getUserInfo().data_directory);
//                //跳转主页面
//                startActivity(MainActivity.class);
//                //更新手机号
//                if (!StringUtils.isEmpty(UserInfo.getUserInfo().phone_number)) {
//                    AuthUserManager.getAuthUserManager().updateCurrentUserPhone(UserInfo.getUserInfo().phone_number);
//                }
//                finish();
                break;
            case EUser_App_All_Config_Changed:
                AppConfigInfo appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
                uc.showLoginByPhoneEvent.setValue(appConfigInfo == null || appConfigInfo.phone_code_login);
                break;
            default:
                break;
        }
    }

    private void sendDefaultCode() {
        showProgress();
        TelegramManager.getTelegramManager().checkAuthenticationCode(getApplication(), "88888", new TgResultBlock<TgResponse>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                hideProgress();
                if (!obj.ok) {
                    showErrorTip("登录失败");
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                hideProgress();
                showErrorTip(getString(R.string.request_error));
            }
        });
    }

    public BindingCommand countryOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startContainerActivityForResult(CountryPickFragment.class.getCanonicalName(), 1);
        }
    });

    public BindingCommand finishOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            clearData();
            finish();
        }
    });

    public void setCountry(String country) {
        this.country.set(Country.fromJson(country));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public BindingCommand isReadOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            isRead.set(!isRead.get());
        }
    });

    public void clearData() {
        AppConfigInfo appConfigInfo = AppConfigInfo.getAppWithoutLoginConfigInfo();
        if (appConfigInfo == null || !appConfigInfo.phone_code_login) {
            TelegramManager.getTelegramManager().cleanCurrentData();
        }
    }
}
